﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Xml;

namespace Reckoning
{
    /// <summary>
    /// Default implementation of reference data file
    /// </summary>
    public class ReferenceDataFile : IReferenceDataFile
    {
        #region IReferenceDataFile Methods
        public bool Read(string path,
                         out Dictionary<string, uint> referenceData,
                         out uint totalCount,
                         out string softwareVersion)
        {
            bool ret = true;
            referenceData = new Dictionary<string, uint>();
            totalCount = 0;
            softwareVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
            try
            {
                using (XmlTextReader xr = new XmlTextReader(path))
                {
                    xr.Read();

                    bool val = xr.MoveToFirstAttribute();
                    do
                    {
                        if (val && xr.Name == "SoftwareVersion")
                        {
                            softwareVersion = xr.GetAttribute("SoftwareVersion");
                            break;
                        }
                        val = xr.MoveToNextAttribute();
                    }
                    while (val);

                    while (xr.Read())
                    {
                        switch (xr.NodeType)
                        {
                            case XmlNodeType.Element:
                                if (xr.Name == "WordCount")
                                {
                                    xr.ReadStartElement("WordCount");
                                    string word = xr.ReadElementString("Word");
                                    uint count = (uint)Convert.ToInt32(xr.ReadElementString("Count"));
                                    referenceData[word] = count;
                                    totalCount += count;
                                }
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
            catch
            {
                // if there's some error, just assume reference data is bad
                // from the point of the error onwards
                ret = false;
            }

            return ret;
        }

        public bool Write(string path,
                          Dictionary<string, uint> referenceData)
        {
            bool ret = true;
            try
            {
                using (XmlTextWriter xw = new XmlTextWriter(path, new UTF8Encoding(false)))
                {
                    xw.Formatting = Formatting.Indented;
                    xw.WriteStartElement("ReferenceData", "Reckoning");

                    string softwareVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
                    xw.WriteAttributeString("SoftwareVersion", softwareVersion);

                    foreach (KeyValuePair<string, uint> pair in referenceData)
                    {
                        xw.WriteStartElement("WordCount");
                        xw.WriteElementString("Word", pair.Key);
                        xw.WriteElementString("Count", pair.Value.ToString());
                        xw.WriteEndElement();
                    }

                    xw.WriteEndElement();
                }
            }
            catch
            {
                ret = false;
            }

            return ret;
        }
        #endregion
    }
}
